﻿using System;
using System.Linq;

namespace Dpy.Math.Algebra
{
    public static class Equation
    {
        /// <summary>
        /// Solves linear equation of type ax+b=0.
        /// </summary>
        /// <param name="a">The Linear coeficient a.</param>
        /// <param name="b">The free coeficient b.</param>
        /// <returns>The solution x of the equations. If no real solution returns null. If every real x is solution returns NaN.</returns>
        public static double? SolveLinear(double a, double b)
        {
            if (a.IsZero())
            {
                return b.IsZero()
                    ? (double?)double.NaN
                    : null;
            }
            else
            {
                return -b / a;
            }
        }

        /// <summary>
        /// Solves quadratic equation of type ax^2+bx+c=0.
        /// </summary>
        /// <param name="a">The quadratic coeficient a.</param>
        /// <param name="b">The linear coeficient b.</param>
        /// <param name="c">The free coeficient c.</param>
        /// <returns>The solutions in double array. If there are no real solutions the array is empty. If every real x is solution returns null.</returns>
        public static double[] SolveQuadratic(double a, double b, double c)
        {
            if (a.IsZero())
            {
                double? linearSolution = Equation.SolveLinear(b, c);
                if (linearSolution.HasValue)
                {
                    return linearSolution.Value.IsRealNumber()
                        ? new double[] { linearSolution.Value }
                        : null;
                }
                else
                {
                    return new double[] { };
                }
            }
            else
            {
                double d = b * b - 4 * a * c;

                if (d.IsZero())
                {
                    return new double[] { -b / (2 * a) };
                }
                else if (d > 0)
                {
                    double sqrtD = System.Math.Sqrt(d);

                    return new double[] { 
                        (-b + sqrtD) / (2 * a), 
                        (-b - sqrtD) / (2 * a) };
                }
                else
                {
                    return new double[] { };
                }
            }
        }
    }
}
